package com.laen.demo;

import akka.actor.*;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.TimeoutException;

public class AkkaDemo {

  private static final Logger log = LoggerFactory.getLogger(AkkaDemo.class);

  @Test
  public void testActor() throws TimeoutException {
    ActorSystem actorSystem = ActorSystem.create();
    ActorRef actorRef = actorSystem.actorOf(Props.create(MyActor.class), "actor1");
    Inbox inbox = Inbox.create(actorSystem);
    inbox.watch(actorRef);
    inbox.send(actorRef, "hello");
    inbox.receive(Duration.ofSeconds(2)).equals("world");

    ActorSelection actorSelection = actorSystem.actorSelection("/user/actor1/child");
    actorSelection.tell(PoisonPill.getInstance(),actorSelection.anchor());


    log.info("{}",inbox.receive(Duration.ofSeconds(10)) instanceof Terminated);


  }

  public static class MyActor extends UntypedAbstractActor {


    public MyActor() {

    }

    @Override
    public void preRestart(Throwable reason, Optional<Object> message) throws Exception {
      log.info("preRestart {}", self().path());

      super.preRestart(reason, message);
    }

    @Override
    public void preStart() throws Exception {
      log.info("preStart");
      super.preStart();
    }

    @Override
    public void postRestart(Throwable reason) throws Exception {
      log.info("postRestart");
      super.postRestart(reason);
    }

    @Override
    public void postStop() throws Exception {
      log.info("postStop {}",self().path());
      super.postStop();
    }

    @Override
    public void onReceive(Object message) throws Throwable {
      log.info("onReceive {} from path {}", message, getSender().path());
      if(message instanceof Terminated) {
        getSender().tell("world", ActorRef.noSender());
      } else if ("hello".equals(message)){
        context().watch(context().actorOf(Props.create(MyActor.class),"child"));
        getSender().tell("world", self());
      }
    }
  }
}
